package com.jl.magic.extract;


/**
 * @author 44845
 * 量化后的3D像素立方体
 */
public class PixelCube {

    /**
     * 区间化的像素值[0, 1<<MMCQ.SIGBITS-1]，即[0,31]
     */
    int r1;
    int r2;
    int g1;
    int g2;
    int b1;
    int b2;

    /**
     * 像素立方体体积
     */
    private Integer volume;
    private Integer count;
    private int[] avg;

    /**
     * 立方体里每个点存在的像素数
     */
    private final int[] histories;

    public PixelCube(int r1, int r2, int g1, int g2, int b1, int b2, int[] histories) {
        this.r1 = r1;
        this.r2 = r2;
        this.g1 = g1;
        this.g2 = g2;
        this.b1 = b1;
        this.b2 = b2;

        this.histories = histories;
    }

    /**
     * Cube体量
     *
     * @return 体积
     */
    public int volume() {
        if (volume == null) {
            volume = ((r2 - r1 + 1) * (g2 - g1 + 1) * (b2 - b1 + 1));
        }
        return volume;
    }

    /**
     * 3D空间里像素点的总量
     *
     * @return 总的像素点数量
     */
    public int count() {
        if (count == null) {
            int total = 0;
            int i, j, k, index;
            for (i = r1; i <= r2; i++) {
                for (j = g1; j <= g2; j++) {
                    for (k = b1; k <= b2; k++) {
                        index = MMCQ.getColorIndex(i, j, k);
                        total += histories[index];
                    }
                }
            }
            count = total;
        }
        return count;
    }

    /**
     * 立方体里所有像素点的rgb平均值
     *
     * @return 平均像素值
     */
    public int[] average() {
        if (avg == null) {
            //立方体里总像素个数
            int pixelsOfTotal = 0;

            int redSum = 0;
            int greenSum = 0;
            int blueSum = 0;

            int pixelsOfPerDot, i, j, k, index;

            int enlarge = 1 << MMCQ.QUANTIZE_MOVE_BITS;

            for (i = r1; i <= r2; i++) {
                for (j = g1; j <= g2; j++) {
                    for (k = b1; k <= b2; k++) {
                        index = MMCQ.getColorIndex(i, j, k);
                        //i,j,k点的像素个数
                        pixelsOfPerDot = histories[index];
                        pixelsOfTotal += pixelsOfPerDot;
                        //i,j,k点所有像素red值总和
                        redSum += (pixelsOfPerDot * (i + 0.5) * enlarge);
                        greenSum += (pixelsOfPerDot * (j + 0.5) * enlarge);
                        blueSum += (pixelsOfPerDot * (k + 0.5) * enlarge);
                    }
                }
            }

            if (pixelsOfTotal > 0) {
                avg = new int[]{(redSum / pixelsOfTotal), (greenSum / pixelsOfTotal), (blueSum / pixelsOfTotal)};
            } else {
                //中心点的像素值
                avg = new int[]{(enlarge * (r1 + r2 + 1) / 2), (enlarge * (g1 + g2 + 1) / 2), (enlarge * (b1 + b2 + 1) / 2)};
            }
        }

        return avg;
    }

    /**
     * 判断像素点是否在像素立方体里
     *
     * @param pixel int[]{255,128,189}
     * @return true 在
     */
    public boolean contains(int[] pixel) {
        int red = pixel[0] >> MMCQ.QUANTIZE_MOVE_BITS;
        int green = pixel[1] >> MMCQ.QUANTIZE_MOVE_BITS;
        int blue = pixel[2] >> MMCQ.QUANTIZE_MOVE_BITS;
        return (red >= r1 && red <= r2 && green >= g1 && green <= g2 && blue >= b1
                && blue <= b2);
    }

    @Override
    protected PixelCube clone() {
        return new PixelCube(r1, r2, g1, g2, b1, b2, histories);
    }

    @Override
    public String toString() {
        return "r1: " + r1 + " / r2: " + r2 + " / g1: " + g1 + " / g2: " + g2 + " / b1: " + b1
                + " / b2: " + b2;
    }

}
